Site Automation
Site creation, rebuild, and publishing are managed by this GNU Make makefile
(Make Doc)
SHELL := $(shell which bash) # Copyright (C) 2017 George Clemmer # Author: George Clemmer myglc2 at gmail dot com # Keywords: emacs, github pages, orgmode, org-mode, bootstrap # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; see the file COPYING. If not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # Commentary: # emacsite -- easy Emacs web sites # Please also see README.org. # emacsite uses GNU Make and GNU Emacs to automate the creation of web # sites on GitHub. Simple 'make' commands create a repo, build the # site, and publish it to GitHub Pages. # Make builds the site by running an Emacs server and using # emacsclient to request HTML export of '.org' page source files. 'Org # mode' markup in these files controls content display. 'ox-twbs.el', # which uses the Bootstrap front-end framework to produce mobile first # responsive sites, is used to export the pages to HTML. # The server is started with 'make start'. Subsequent 'make' commands # may be issued using 'M-x shell make', 'M-x eshell make', or 'M-x # compile' from within the Emacs server or from another emacs instance # or from the command line. # Source files may be edited using the Emacs server, another instance # of emacs, or a different editor altogether. # The site may be previewed locally with 'make preview'. A change may # be committed with 'make commit', and published to GitHub with 'make # gh'. Finally the emacs server may be killed with 'make stop'. # Menus are generated by including into a page's source the # 'header.org' file that contains the Emacs Lisp 'menu' code block # that generates bootstrap menus. # Emacs 'Font Lock' determines the colors and faces used to display # code and 'ox-twbs.el' uses 'htmlize.el' to produce WYSIWYG export of # such code to HTML. However, when, as is typically the case, the # Emacs server is run as a daemon or in batch mode, font lock is not # active and code is exported in black and white. To overcome this, # Emacs is started with a GUI and switched to be a server. This causes # font lock to be active, produces WYSIWYG code export, and allows the # appearance of exported code to be customized by loading an Emacs # 'Custom Theme' # The markup menu and sub-directory provide exemplar Org mode markup # and bootstrap button automation. # To increase reproducibility, 'ox-twbs.el' and 'htmlize.el' sources # are provided and loaded. REMOTE := github.com # for debugging ... # ... to print all $(warning ...)'s # DEBUG=1 make: # ... to print the value of SYMBOL # make print-<SYMBOL>> print-%: @echo $* = $($*) @echo $*\'s origin is $(origin $*) # ignore default GNU suffixes .SUFFIXES: # select a browser UNAME := $(shell uname) ifeq ($(UNAME),Linux) BROWSER := $(firstword \ $(shell which chromium 2> /dev/null) \ $(shell which icecat 2> /dev/null) \ $(shell which conkeror 2> /dev/null)\ ) else ifeq ($(UNAME),Darwin) BROWSER := open -a Google\ Chrome --args --allow-file-access-from-files BROWSER := open -a Firefox.app BROWSER := open -a Safari endif $(if $(DEBUG),$(warning BROWSER: $(BROWSER)),) # determine URL, user and repo name from 'git remote origin' GITHUB-URL := $(subst .git,,$(shell git config --get remote.origin.url)) $(if $(DEBUG),$(warning GITHUB-URL $(GITHUB-URL)),) GITHUB-USR-REPO := $(subst git@github.com:,,$(GITHUB-URL)) $(if $(DEBUG),$(warning GITHUB-USR-REPO $(GITHUB-USR-REPO)),) GITHUB-USR := $(firstword $(subst /, ,$(GITHUB-USR-REPO))) $(if $(DEBUG),$(warning GITHUB-USR $(GITHUB-USR)),) GITHUB-REPO := $(lastword $(subst /, ,$(GITHUB-USR-REPO))) $(if $(DEBUG),$(warning GITHUB-REPO $(GITHUB-REPO)),) # Org-mode page sources # org files ORGFILES := $(shell find . -maxdepth 3 -name "*.org") $(if $(DEBUG),$(warning ORGFILES: $(ORGFILES)),) # HTML page targets HTMLxORG := $(addsuffix .html,$(basename $(ORGFILES))) $(if $(DEBUG),$(warning HTMLxORG: $(HTMLxORG)),) # make the site .PHONY: all all: pages echo To preview, open: $(PWD)/index.html # preview the site locally .PHONY: preview preview: pages $(BROWSER) $(PWD)/index.html & # export all .org files to .html .PHONY: pages pages: $(HTMLxORG) # ensure we are on master ONMASTER = if [ "$$(git rev-parse --abbrev-ref HEAD)" != "master" ]; then echo; echo "*** You are on '$$(git rev-parse --abbrev-ref HEAD)' branch" ; echo "*** Please check out 'master'" ; echo ; exit 1 ; fi # is the working tree clean? CLEAN = if [ -n "$$(git status --porcelain --untracked-files=no --short)" ]; then echo "Please 'make commit' or 'stash' your changes to:"; git status --short; exit 1 ; fi # verify the server is not running and start it on home page .PHONY: start start: if ! emacsclient -s emacsite-server --eval '(concat "The Server was Already Running")'; then emacs $(OPTIONS) --load=lisp/htmlize.el --load=lisp/ox-twbs.el --eval="(progn (setq org-confirm-babel-evaluate nil)(setq server-name \"emacsite-server\")(server-start)(find-file \"index.org\")(shell))"; fi; # use emacsclient to export an .org file passing reldir ("$(@D)") in for use by header.org menu code. %.html: %.org header.org $(ONMASTER) $(RM) -f $*.html $*.html* if ! emacsclient -s emacsite-server --eval '(progn (setq reldir "$(@D)") (set-buffer (find-file-noselect "$*.org")) (org-twbs-export-to-html) (concat "$*.org" " >>> " "$*.html"))'; then echo; printf "The Emacs server is not running \n"; printf "Please type 'make start' \n"; echo; exit 1; fi # stop the server .PHONY: stop stop: -emacsclient -s emacsite-server --eval '(kill-emacs)' # emacsite include dependencies about/gnumake.html: makefile about/menus.html: header.org ./markup/code-markup.html: ./markup/code.org ./markup/code-buttons.org ./markup/code.html: ./markup/code-buttons.org ./markup/headlines-markup.html: ./markup/headlines.org ./markup/headlines-buttons.org ./markup/headlines.html: ./markup/headlines-buttons.org ./markup/images-markup.html: ./markup/images.org ./markup/images-buttons.org ./markup/images.html: ./markup/images-buttons.org ./markup/inline-markup.html: ./markup/inline.org ./markup/inline-buttons.org ./markup/inline.html: ./markup/inline-buttons.org ./markup/lists-markup.html: ./markup/lists.org ./markup/lists-buttons.org ./markup/lists.html: ./markup/lists-buttons.org ./markup/literal-markup.html: ./markup/literal.org ./markup/literal-buttons.org ./markup/literal.html: ./markup/literal-buttons.org ./markup/paragraphs-markup.html: ./markup/paragraphs.org ./markup/paragraphs-buttons.org ./markup/paragraphs.html: ./markup/paragraphs-buttons.org ./markup/tables-markup.html: ./markup/tables.org ./markup/tables-buttons.org ./markup/tables.html: ./markup/tables-buttons.org # publish to GitHub .PHONY: gh gh: .gh-update echo To view the site open: https://$(GITHUB-USR).github.io/$(GITHUB-REPO)/ # view on GitHub .PHONY: view view: .gh-update $(BROWSER) https://$(GITHUB-USR).github.io/$(GITHUB-REPO)/ # commit changes MESSAGE ?= $(shell bash -c 'read -s -p "Commit message: " pwd; echo $$pwd') .PHONY: commit commit: $(ONMASTER) git add . ; git commit -m "$(MESSAGE)" # create a GitHub site repo # use the current directory name for the reponame NEWREPO := $(notdir $(CURDIR)) $(if $(DEBUG),$(warning NEWREPO: $(NEWREPO)),) .PHONY: repo repo: $(ONMASTER) $(CLEAN) # save upstream repo reference ... -git remote rename origin upstream # ... or, forget about it ... # -git remote remove origin bash -c 'read -s -p "Please enter your GitHub Username: " username; echo $$username > .username' curl -i -u $$(< .username) -d "{ \"name\": \"$(NEWREPO)\", \"homepage\": \"https://$$(< .username).github.io/$(NEWREPO)/\", \"private\": true}" https://api.github.com/user/repos git remote add origin -f git@$(REMOTE):$$(< .username)/$(NEWREPO).git git push origin -u master:master rm -f .username # publish if pages are newer than the GitHub sentinel .gh-update: $(HTMLxORG) $(ONMASTER) $(CLEAN) # push git push origin -u master:master # delete previous gh-pages branch # revision history for *.html -git branch -D gh-pages # make a new gh-pages branch git branch gh-pages git checkout gh-pages # check in the pages git add -f $(HTMLxORG) git commit -m "Github pages" # delete the old gh-pages branch -git push origin :gh-pages # ... and push the new one git push -u origin gh-pages:gh-pages # rewind our local master branch keeping .html files git symbolic-ref HEAD refs/heads/master git rm --cached $(HTMLxORG) touch .gh-update # remove all pages .PHONY: clean clean: $(RM) -f $(HTMLxORG) *.html~